﻿namespace FeedbackBrowser
{
    using System;
    using System.Diagnostics;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media.Animation;
    using System.Windows.Media.Imaging;

    using ExtendedWindowsControls;

    using Microsoft.TeamFoundation;
    using Microsoft.TeamFoundation.Client;
    using Microsoft.TeamFoundation.WorkItemTracking.Client;

    public partial class MainNotifyWindow : Window
    {
        #region Fields

        private readonly ExtendedNotifyIcon _extendedNotifyIcon;
        private readonly Storyboard _gridFadeInStoryBoard;
        private readonly Storyboard _gridFadeOutStoryBoard;

        private Uri _collectionUri;

        #endregion Fields

        #region Constructors

        /// <summary>
        /// </summary>
        public MainNotifyWindow()
        {
            // Create a manager (ExtendedNotifyIcon) for handling interaction with the notification icon and wire up events.
            _extendedNotifyIcon = new ExtendedNotifyIcon();
            _extendedNotifyIcon.MouseLeave += extendedNotifyIcon_OnHideWindow;
            _extendedNotifyIcon.MouseMove += extendedNotifyIcon_OnShowWindow;
            _extendedNotifyIcon.targetNotifyIcon.Text = Properties.Resources.MainNotifyWindow_MainNotifyWindow_Connecting;
            SetNotifyIcon("Red");

            InitializeComponent();

            // Set the startup position and the startup state to "not visible"
            SetWindowToBottomRightOfScreen();
            Opacity = 0;
            uiGridMain.Opacity = 0;

            // Locate these storyboards and "cache" them - we only ever want to find these once for performance reasons
            _gridFadeOutStoryBoard = (Storyboard)TryFindResource("gridFadeOutStoryBoard");
            _gridFadeOutStoryBoard.Completed += GridFadeOutStoryBoardCompleted;
            _gridFadeInStoryBoard = (Storyboard)TryFindResource("gridFadeInStoryBoard");
            _gridFadeInStoryBoard.Completed += GridFadeInStoryBoardCompleted;

            LoadFeedbackRequests();
        }

        #endregion Constructors

        #region Methods

        private void BtnConfigureClick(object sender, RoutedEventArgs e)
        {
            SignIn();
            FillFeedbacks();
        }

        private void BtnConfigureMouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            // TODO: Add event handler implementation here.
        }

        private void BtnRefreshClick(object sender, RoutedEventArgs e)
        {
            FillFeedbacks();
        }

        private void CloseButtonClick(object sender, RoutedEventArgs e)
        {
            _extendedNotifyIcon.Dispose();
            Close();
        }

        void extendedNotifyIcon_OnHideWindow()
        {
            if (PinButton.IsChecked == true) return; // Dont hide the window if its pinned open

            _gridFadeInStoryBoard.Stop(); // Stop the fade in storyboard if running.

            if (uiGridMain.Opacity == 1 && this.Opacity == 1)
                _gridFadeOutStoryBoard.Begin();
            else // Just hide the window and grid
            {
                uiGridMain.Opacity = 0;
                Opacity = 0;
            }
        }

        void extendedNotifyIcon_OnShowWindow()
        {
            _gridFadeOutStoryBoard.Stop();
            Opacity = 1; // Show the window (backing)
            Topmost = true; // Very rarely, the window seems to get "buried" behind others, this seems to resolve the problem
            if (uiGridMain.Opacity > 0 && uiGridMain.Opacity < 1) // If its animating, just set it directly to visible (avoids flicker and keeps the UX slick)
            {
                uiGridMain.Opacity = 1;
            }
            else if (uiGridMain.Opacity == 0)
            {
                _gridFadeInStoryBoard.Begin();  // If it is in a fully hidden state, begin the animation to show the window
            }
        }

        private void FillFeedbacks()
        {
            _collectionUri = new Uri(Properties.Settings.Default.TfsCollectionUri);

            var tfs2 = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(_collectionUri);
            tfs2.EnsureAuthenticated();
            var wist = (WorkItemStore)tfs2.GetService(typeof(WorkItemStore));
            Project tp = wist.Projects[Properties.Settings.Default.TfsProjectName];

            var fReq = @"SELECT [System.Id], [System.WorkItemType]," +
                       "  [System.State], [System.AssignedTo], [System.Title] " +
                       "  FROM WorkItems " +
                       "  WHERE [System.TeamProject] = '" + tp.Name +
                       "' AND [System.WorkItemType]='Feedback Request' and [System.State]='Active' and [System.AssignedTo] =@me ORDER BY [System.Id] DESC";

            var queryFeedbacks = new Query(wist, fReq);
            WorkItemCollection feedbacks = queryFeedbacks.RunQuery();

            TitleLabel.Content = String.Format("Feedback Browser   {0} requests", feedbacks.Count);

            lstFeedbackRequests.ItemsSource = feedbacks;
            _extendedNotifyIcon.targetNotifyIcon.Text = Properties.Resources.MainNotifyWindow_FillFeedbacks_Feedback_Browser__Connected;
            SetNotifyIcon("Green");
        }

        void GridFadeInStoryBoardCompleted(object sender, EventArgs e)
        {
            Opacity = 1;
        }

        void GridFadeOutStoryBoardCompleted(object sender, EventArgs e)
        {
            Opacity = 0;
        }

        private void List1SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string col = Properties.Settings.Default.TfsCollectionUri.Replace("https://", "");
            var id = ((WorkItem)((ListView)sender).SelectedItem).Id;
            string pro = Properties.Settings.Default.TfsProjectName;

            Process.Start(string.Format("mfbclients://{0}/p:{1}?rid={2}",col,pro,id));
        }

        private void LoadFeedbackRequests()
        {
            try
            {
                if (string.IsNullOrEmpty(Properties.Settings.Default.TfsCollectionUri))
                {
                    SignIn();
                }

                FillFeedbacks();
            }
            catch (TeamFoundationServerUnauthorizedException)
            {
                SignIn();
                FillFeedbacks();
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }

        private void MenuItemClick(object sender, RoutedEventArgs e)
        {
            string col = Properties.Settings.Default.TfsCollectionUri.Replace("https://", "");
            var id = ((WorkItem) ((ListView) sender).SelectedItem).Id;
            string pro = Properties.Settings.Default.TfsProjectName;

            Process.Start(string.Format("mfbclients://{0}/p:{1}?rid={2}", col, pro, id));
        }

        private void PinButtonClick(object sender, RoutedEventArgs e)
        {
            PinImage.Source = PinButton.IsChecked == true ? new BitmapImage(new Uri("pack://application:,,/Images/Pinned.png")) : new BitmapImage(new Uri("pack://application:,,/Images/Un-Pinned.png"));
        }

        private void SetNotifyIcon(string iconPrefix)
        {
            var streamResourceInfo = Application.GetResourceStream(new Uri("pack://application:,,/Images/" + iconPrefix + "Orb.ico"));
            if (streamResourceInfo != null)
            {
                System.IO.Stream iconStream = streamResourceInfo.Stream;
                _extendedNotifyIcon.targetNotifyIcon.Icon = new System.Drawing.Icon(iconStream);
            }
        }

        private void SetWindowToBottomRightOfScreen()
        {
            Left = SystemParameters.WorkArea.Width - Width - 10;
            Top = SystemParameters.WorkArea.Height - Height;
        }

        private void SignIn()
        {
            var tpp = new TeamProjectPicker(TeamProjectPickerMode.SingleProject, false, new UICredentialsProvider());

            tpp.ShowDialog();

            if (tpp.SelectedTeamProjectCollection != null)
            {
                Properties.Settings.Default.TfsCollectionUri = "https://" +
                                                               tpp.SelectedTeamProjectCollection.Name.Replace(
                                                                   '\\', '/');
                Properties.Settings.Default.TfsProjectName = tpp.SelectedProjects[0].Name;

                _collectionUri = new Uri(Properties.Settings.Default.TfsCollectionUri);
                var provider = new UICredentialsProvider();
                var tfs1 = new TfsTeamProjectCollection(_collectionUri, provider);
                tfs1.Authenticate();
                Properties.Settings.Default.Save();
            }
        }

        private void StartClick(object sender, RoutedEventArgs e)
        {
            string col = Properties.Settings.Default.TfsCollectionUri.Replace("https://", "");
            WorkItem wrk = ((FrameworkElement)sender).DataContext as WorkItem;
            var id = wrk.Id;
            string pro = Properties.Settings.Default.TfsProjectName;

            Process.Start(string.Format("mfbclients://{0}/p:{1}?rid={2}", col, pro, id));
        }

        private void UiWindowMainNotificationMouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            // Cancel the mouse leave event from firing, stop the fade out storyboard from running and enusre the grid is fully visible
            _extendedNotifyIcon.StopMouseLeaveEventFromFiring();
            _gridFadeOutStoryBoard.Stop();
            uiGridMain.Opacity = 1;
        }

        private void UiWindowMainNotificationMouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            extendedNotifyIcon_OnHideWindow();
        }

        #endregion Methods
    }
}